/**
 *	@file		mutex.cpp 
 *	@version	1.0a
 *	@author		rpvaras
 *
 *	This file is part of omcpp.
 *	
 *	
 *
 *	omcpp is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.
 *
 *	omcpp is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with omcpp. If not, see <http://www.gnu.org/licenses/>.
 */
#include <omcpp/config.h>
#include <omcpp/mutex.h>
#include <exception>

using namespace omcpp;

#ifdef OMCPP_PLATFORM_WIN32
//--------------------------------------------------------
//--------------------------------------------------------
mutex::mutex()
{
	_hMutex = ::CreateMutex(NULL, FALSE, NULL);
	if(!_hMutex)
		throw std::exception("Failed to initialize mutex");
}
mutex::~mutex()
{
	if(_hMutex)
		::CloseHandle(_hMutex);
}
mutex::mutex(const mutex& copy)
{

}
void mutex::lock()
{
	if(!_hMutex)
		throw std::exception("Mutex is not initialized");
	
	DWORD wResult = ::WaitForSingleObject(_hMutex, INFINITE);

	switch(wResult)
	{
		case WAIT_ABANDONED:
			throw std::exception("Mutex was abandoned");
			break;
		case WAIT_FAILED:
			throw std::exception("Failed to lock mutex");
			break;
		default:
			break;
	}
}
void mutex::release()
{
	if(!_hMutex)
		throw std::exception("Mutex is not initialized");

	if(!::ReleaseMutex(_hMutex))
		throw std::exception("Failed to release mutex");
}
#endif //OMCPP_PLATFORM_WIN32

//--------------------------------------------------------
//--------------------------------------------------------
auto_mutex::auto_mutex(mutex& mtx)
: _mtx(mtx)
{
	_mtx.lock();
}
auto_mutex::~auto_mutex()
{
	_mtx.release();
}